///*
// * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// *       http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package io.iec.edp.caf.security.core.spring.authentication;
//
//import io.iec.edp.caf.session.holder.CafSecurityAPIKeyHolder;
//import lombok.extern.slf4j.Slf4j;
//import lombok.var;
//import org.springframework.context.ApplicationListener;
//import org.springframework.core.Ordered;
//import org.springframework.core.annotation.Order;
//import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.context.SecurityContext;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
//import org.springframework.session.Session;
//import org.springframework.session.SessionRepository;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Method;
//
///**
// * 认证成功后事件（优先级最高），第一时间将Session持久化，解决计划任务和分布式锁中持久化前判断Session无效的问题
// */
//@Slf4j
//@Order(value = Ordered.HIGHEST_PRECEDENCE)
//public class AuthenticationSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {
//
//    private SessionRepository sessionRepository;
//
//    public AuthenticationSuccessListener(SessionRepository sessionRepository) {
//        this.sessionRepository = sessionRepository;
//    }
//
//    @Override
//    public void onApplicationEvent(AuthenticationSuccessEvent authenticationSuccessEvent) {
//        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        if (servletRequestAttributes == null) {
//            return;
//        }
//        HttpServletRequest request = servletRequestAttributes.getRequest();
//
//        //API key场景
//        setAPIKey(request);
//
//        Authentication securityAuth = (Authentication) authenticationSuccessEvent.getSource();
//        //创建一个空的，主要是避免对原有认证逻辑造成影响（SecurityContextHolder.getContext()）
//        SecurityContext context = SecurityContextHolder.createEmptyContext();
//        if (securityAuth.isAuthenticated()) {
//            //SecurityContextHolder.getContext().setAuthentication(securityAuth);
//            context.setAuthentication(securityAuth);
//        }
//        Session session = this.getCurrentSession(request);
//        if (session != null) {
//            session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context);
//            this.sessionRepository.save(session);
//            //SecurityContextHolder.clearContext();
//        }
//    }
//
//    /**
//     * 获取当前Session
//     *
//     * @param request
//     * @return
//     */
//    private Session getCurrentSession(HttpServletRequest request) {
//        var httpSessionWrapper = request.getSession();
//        if (httpSessionWrapper == null)
//            return null;
//        try {
//            Method method = httpSessionWrapper.getClass().getSuperclass().getDeclaredMethod("getSession", null);
//            method.setAccessible(true);
//            return (Session) method.invoke(httpSessionWrapper);
//        } catch (Exception e) {
//            throw new RuntimeException("调用目标错误", e);
//        }
//    }
//
//    /**
//     * 标识api key
//     */
//    private void setAPIKey(HttpServletRequest request) {
//        Object attribute = request.getAttribute("caf-security-spring-authentication");
//        boolean isApiKey = attribute != null && "io.iec.edp.caf.security.apikey.authentication.CafApiKeySpringAuthentication".equals(attribute.getClass().getName());
//
//        CafSecurityAPIKeyHolder.set(isApiKey);
//    }
//}
